added some development tools
[windows-sources.git] / developer / Samples / NET Standard / ParallelExtensionsExtras / Extensions / AggregateExceptionExtensions.cs
blob6429712a9d6a23d8a3fd15a779c9a9aeabcbc658
1 //--------------------------------------------------------------------------
2 //
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 //
5 // File: AggregateExceptionExtensions.cs
6 //
7 //--------------------------------------------------------------------------
9 using System.Collections.Generic;
11 namespace System
13 /// <summary>Extension methods for AggregateException.</summary>
14 public static class AggregateExceptionExtensions
16 /// <summary>Invokes a handler on each Exception contained by this AggregateException.</summary>
17 /// <param name="aggregateException">The AggregateException.</param>
18 /// <param name="predicate">
19 /// The predicate to execute for each exception. The predicate accepts as an argument the Exception
20 /// to be processed and returns a Boolean to indicate whether the exception was handled.
21 /// </param>
22 /// <param name="leaveStructureIntact">
23 /// Whether the rethrown AggregateException should maintain the same hierarchy as the original.
24 /// </param>
25 public static void Handle(
26 this AggregateException aggregateException,
27 Func<Exception, bool> predicate, bool leaveStructureIntact)
29 if (aggregateException == null) throw new ArgumentNullException("aggregateException");
30 if (predicate == null) throw new ArgumentNullException("predicate");
32 // If leaveStructureIntact, use this implementation
33 if (leaveStructureIntact)
35 var result = HandleRecursively(aggregateException, predicate);
36 if (result != null) throw result;
38 // Otherwise, default back to the implementation on AggregateException
39 else aggregateException.Handle(predicate);
42 private static AggregateException HandleRecursively(
43 AggregateException aggregateException, Func<Exception, bool> predicate)
45 // Maintain a list of exceptions to be rethrown
46 List<Exception> innerExceptions = null;
48 // Loop over all of the inner exceptions
49 foreach(var inner in aggregateException.InnerExceptions)
51 // If the inner exception is itself an aggregate, process recursively
52 AggregateException innerAsAggregate = inner as AggregateException;
53 if (innerAsAggregate != null)
55 // Process recursively, and if we get back a new aggregate, store it
56 AggregateException newChildAggregate = HandleRecursively(innerAsAggregate, predicate);
57 if (newChildAggregate != null)
59 if (innerExceptions != null) innerExceptions = new List<Exception>();
60 innerExceptions.Add(newChildAggregate);
63 // Otherwise, if the exception does not match the filter, store it
64 else if (!predicate(inner))
66 if (innerExceptions != null) innerExceptions = new List<Exception>();
67 innerExceptions.Add(inner);
71 // If there are any remaining exceptions, return them in a new aggregate.
72 return innerExceptions.Count > 0 ?
73 new AggregateException(aggregateException.Message, innerExceptions) :
74 null;